<template>
  <div class="mpa-tools-view">
    <span :class="dataIndex === 1 ? 'sys-data-index' : ''" class="maptools-item" @click="navigation(1)">行政区导航</span>
    <span :class="dataIndex === 2 ? 'sys-data-index' : ''" class="maptools-item" @click="navigation(2)">目录树管理</span>
    <el-dropdown trigger="click" @visible-change="navigation(3)"  @command="handleCommand">
      <span :class="dataIndex === 3 ? 'sys-data-index' : ''" class="el-dropdown-link">
        地图测量
        <i class="el-icon-arrow-down el-icon--right"></i>
      </span>
      <el-dropdown-menu v-slot="dropdown">
        <el-dropdown-item command="a" icon="el-icon-data-board">距离测量</el-dropdown-item>
        <el-dropdown-item command="b" icon="el-icon-pie-chart">面积测量</el-dropdown-item>
        <el-dropdown-item command="g" icon="el-icon-data-board">自定义距离测量</el-dropdown-item>
        <el-dropdown-item command="h" icon="el-icon-pie-chart">自定义面积测量</el-dropdown-item>
      </el-dropdown-menu>
    </el-dropdown>
    <el-dropdown trigger="click" @visible-change="navigation(4)" @command="handleCommand">
      <span :class="dataIndex === 4 ? 'sys-data-index' : ''" class="el-dropdown-link">
        更多功能
        <i class="el-icon-arrow-down el-icon--right"></i>
      </span>
      <el-dropdown-menu v-slot="dropdown">
        <el-dropdown-item command="c" icon="el-icon-search">空间查询</el-dropdown-item>
        <el-dropdown-item command="d" icon="el-icon-film">多屏对比</el-dropdown-item>
        <el-dropdown-item command="e" icon="el-icon-reading">卷帘分析</el-dropdown-item>
        <el-dropdown-item command="f" icon="el-icon-printer">地图打印</el-dropdown-item>
        <el-dropdown-item command="i" icon="el-icon-edit-outline">自定义弹窗</el-dropdown-item>
      </el-dropdown-menu>
    </el-dropdown>
    <span :class="dataIndex === 5 ? 'sys-data-index' : ''" class="maptools-item" @click="navigation(5)">清屏</span>
  </div>
</template>

<script>
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js"; // 加载要素图层
import SketchViewModel from "@arcgis/core/widgets/Sketch/SketchViewModel.js"; // 自定义绘图
import Graphic from "@arcgis/core/Graphic.js"; // 矢量表现
import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer.js"; // 存放Graphic数据图层
import Swipe from "@arcgis/core/widgets/Swipe.js"; // 卷帘控件
import * as print from "@arcgis/core/rest/print.js"; //打印模块提供的一种方法
import PrintParameters from "@arcgis/core/rest/support/PrintParameters.js"; // 打印时输入参数。
import PrintTemplate from "@arcgis/core/rest/support/PrintTemplate.js"; //定义打印使用的布局模板选项
import AreaMeasurement2D from "@arcgis/core/widgets/AreaMeasurement2D.js"; // 二维地图面积测量控件
import DistanceMeasurement2D from "@arcgis/core/widgets/DistanceMeasurement2D.js"; // 二维地图距离测量控件
import * as geometryService from "@arcgis/core/rest/geometryService.js"; // 用于对几何执行各种操作，例如面积、长度、投影、简化、缓冲和关系
import LengthsParameters from "@arcgis/core/rest/support/LengthsParameters.js"; // 计算长度参数
import AreasAndLengthsParameters from "@arcgis/core/rest/support/AreasAndLengthsParameters.js"; // 计算面积参数

export default {
  name: "mpaTools",
  data() {
    return {
      dataIndex:1,
      directory:true,
      // 空间查询结果
      defaultQueryResult:[],
      // 测量控件
      measurementWidget:''
    }
  },
  created() {
    this.$emit('navigation',this.dataIndex)
  },
  methods:{
    navigation(index) {
      this.dataIndex = index;
      this.$emit('navigation',index)
    },
    // 更多功能
    handleCommand(command) {
      if (command === 'a') {
        // 距离测量 (使用控件)
        this.instDistanceMap();
      } else if (command === 'b') {
        // 面积测量 (使用控件)
        this.instAreaMap();
      } else if (command === 'c') {
        // 空间查询
        this.initSpatialQuery()
      } else if (command === 'd') {
        // 多屏对比
        this.$router.push('/oneMap/shutter');
      } else if (command === 'e') {
        // 卷帘分析
        this.initSwipe()
      } else if (command === 'f') {
        // 卷帘打印
        this.printView()
      } else if (command === 'g') {
        // 自定义距离测量
        this.customInstDistanceMap();
      } else if (command === 'h') {
        // 自定义面积测量
        this.customInstAreaMap();
      } else {
        // 自定义弹窗
        this.customPopup();
      }
    },
    // 空间查询绘图
    async initSpatialQuery() {
      let _that = this;
      // 获取地图视图
      let view = _that.$store.state.mapView;
      // 1.绘制面状区域
      // 查找上一次绘制的图层
      const resultLayer = view.map.findLayerById('polygonGraphicLayer');
      // 删除存放数据的图层
      if (resultLayer) view.map.remove(resultLayer);

      // 实例化一个 GraphicsLayer 图层
      let graphicsLayer = new GraphicsLayer({
        id:'polygonGraphicLayer',
        elevationInfo:{
          mode:'on-the-ground'
        }
      });
      // 把GraphicsLayer图层添加到地图上
      view.map.add(graphicsLayer)

      // 定义绘制形状的样式符号
      const pointSymbol = {
        // type = 'simple-fill', 'picture-fill', 'picture-marker', 'simple-line', 'simple-marker', 'text', 'label-3d', 'line-3d', 'mesh-3d', 'point-3d', 'polygon-3d', 'web-style', 'cim')
        type:'simple-fill',
        // 填充颜色
        color: [216, 30, 6, 0.4],
        // 面状边框样式
        style:'solid',
        outline: {
          width: 1,
          color: '#d81e06'
        }
      }
      // 绘制形状的方法
      const sketchViewModel = new SketchViewModel({
        // Graphic 更新的时候是否触发click事件
        updateOnGraphicClick:false,
        // 绘制的地图
        view,
        // 存放到 graphicsLayer
        layer: graphicsLayer,
        // 样式符号
        pointSymbol
      });
      // 指定要绘制的形状 polygon代表面（（"point 点"|"multipoint"|"polyline 线"|"polygon 面"|"rectangle"|"circle"））
      await sketchViewModel.create('polygon');
      // 监听绘制完成事件 create-complete，不支持调用个人定义的方法
      sketchViewModel.on("create-complete", function(event) {
        // 几何图形表现
        const graphic = new Graphic({
          geometry: event.geometry,
          symbol: sketchViewModel.graphic.symbol,
        });
        // 把几何图形添加到新图层上
        GraphicsLayer.add(graphic)
      });
      // 监听绘制事件，绘制完成后执行查询
      sketchViewModel.on("create", function(event) {
        // state === "complete" 也就是绘制完成
        if (event.state === "complete") {
          // 执行空间查询
          _that.handleSpaceQuery(event.graphic)
        }
      });
    },
    // 执行空间查询
    async handleSpaceQuery(graphic) {
      let _that = this;
      // 获取地图视图
      let view = _that.$store.state.mapView;
      let showTable = false;
      // 查找业务图层
      const resultLayer = view.map.findLayerById('layerid');
      // 删除存放数据的图层
      if (!resultLayer) {
        _that.$message({
          message: '尚未添加业务图层，不能执行空间查询',
          type: 'warning'
        });
        // 阻止后面的代码执行
        return true;
      }
      // 空间查询只能使用要素图层中的 createQuery 实例化数据
      const queryPoint = resultLayer.createQuery();
      // 绑定geometry，绘制的面状区域geometry
      queryPoint.geometry = graphic.geometry;
      // 查询业务图层
      let results = await resultLayer.queryFeatures(queryPoint);
      let currentData = [];
      // 查询出来的数据
      if (results.features.length > 0) {
        // 符号化渲染图层
        await _that.renderResultLayer(results.features);
        // 实例化表格数据
        let features = results.features
        features.map(item => {
          currentData.push({
            name:item.attributes.name,
            address:item.attributes.address,
            lng:item.attributes.lng,
            lat:item.attributes.lat,
            province:item.attributes.province,
            economize:item.attributes.economize,
            market:item.attributes.market,
          })
        })
      }
      // 修改空间查询图表所需参数
      _that.$store.commit('modifyTableData',currentData);
      _that.$store.commit('modifyShowTable',true);
      _that.$emit('gettersCurrentData',currentData,showTable)
      _that.$message({
        message: `查询成功，共查询到${results.features.length}数据`,
        type: 'success'
      });
    },
    // 符号化渲染图层
    async renderResultLayer(features) {
      let _that = this;
      // 获取地图视图
      let view = _that.$store.state.mapView;
      // 查找上一次绘制的图层
      const resultLayer = view.map.findLayerById('initResultLayer');
      // 删除图层
      if (resultLayer) view.map.remove(resultLayer);
      // 转换数据
      const resultData = _that.translateLonLat(features);
      // 实例化弹窗 "esri/PopupTemplate" 内置弹窗
      let template = {
        title:'{name}',
        content:[
          {
            type:'fields',
            fieldInfos:[{
              fieldName:'name',
              label:'火车站名称'
            },{
              fieldName:'address',
              label:'描述'
            },{
              fieldName:'economize',
              label:'省'
            },{
              fieldName:'market',
              label:'市'
            }]
          }
        ]
      }
      // 实例化图层
      const layer = new FeatureLayer({
        source: resultData,
        id:"initResultLayer",
        objectIdField: "ObjectID",
        // 指定给层的渲染器 渲染成什么样子
        renderer: {
          type: "simple", // SimpleRenderer()
          // 符号样式
          symbol: {
            type: "picture-marker", // "esri/symbols/PictureMarkerSymbol" 图片渲染
            url:`static/icon/train.png`, // 图片路径
            width: '20px',
            height: '20px'
          }
        },
        // 用来指定字段的数据类型
        fields:[
          {
            name:'OBJECTID',
            type:'oid'
          },
          {
            name:'name',
            type:'string'
          },
          {
            name:'address',
            type:'string'
          },
          {
            name:'economize',
            type:'string'
          },
          {
            name:'market',
            type:'string'
          }
        ],
        // 添加弹窗
        popupTemplate:template
      });
      view.map.add(layer);
    },
    // 转换数据
    translateLonLat(data) {
      console.log(data);
      if (data.length > 0) {
        let geoData = [];
        data.map((value,key) => {
          geoData.push({
            geometry:{
              // 符号化数据 point 点数据
              type:'point',
              x:Number(value.attributes.lng),
              y:Number(value.attributes.lat)
            },
            // 弹窗数据
            attributes:{
              ObjectID:key + 1,
              name:value.attributes.name,
              address:value.attributes.address,
              lng:value.attributes.lng,
              lat:value.attributes.lat,
              province:value.attributes.province,
              economize:value.attributes.economize,
              market:value.attributes.market,
            }
          })
        })
        return geoData;
      }
    },
    // 卷帘分析
    initSwipe() {
      let _that = this;
      // 获取底图
      let view = _that.$store.state.mapView;
      // 获取业务图层
      let topLeary = view.map.findLayerById('swipeLearyTop');
      let bottomLeary = view.map.findLayerById('swipeLearyBottom');
      if (topLeary && bottomLeary) {
        let swipe = new Swipe({
          view: view,
          leadingLayers: [topLeary],
          trailingLayers: [bottomLeary],
          direction: "horizontal", // 滑动小部件将从视图的顶部移动到底部 参数 "horizontal"|"vertical"
          position: 50 // 设置在视图中间的位置（50%）
        });
        view.ui.add(swipe);
      } else {
        _that.$message({
          message: '请至少添加两张业务图层!',
          type: 'warning'
        });
      }
    },
    // 自定义打印
    printView() {
      let _that = this;
      // 获取底图
      let view = _that.$store.state.mapView;
      // 打印服务的url
      const url = "https://utility.arcgisonline.com/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export%20Web%20Map%20Task";
      //定义打印使用的布局模板选项 PrintTemplate
      const template = new PrintTemplate({
        // 地图打印的格式 参数"pdf"|"png32"|"png8"|"jpg"|"gif"|"eps"|"svg"|"svgz"
        format: "pdf",
        // 定义地图宽度、高度和 dpi。 width | height | dpi 默认宽高为 800
        exportOptions: {
          dpi: 300
        },
        // 打印输出的布局 纸张
        layout: "a4-portrait",
        // 打印输出的布局 名称等等
        layoutOptions: {
          titleText: "Gillette Stadium",
          authorText: "Thomas B."
        }
      });
      // 打印参数设置 PrintParameters
      const params = new PrintParameters({
        // 指定打印的地图
        view: view,
        // 定义用于打印地图的布局模板
        template: template
      });
      // 执行打印
      print.execute(url, params).then(printResult => {
        console.log(printResult);
        console.log(printResult.url);
        if (printResult.url) {
          window.open(printResult.url);
        }
      }).catch(printError => {
        if (printError) {
          _that.$message({
            message: '打印失败!',
            type: 'error'
          });
        }
      });
    },
    // 距离测量（使用微件）
    instDistanceMap() {
      let _that = this;
      // 获取底图
      let view = this.$store.state.mapView;
      // 判断是否添加过测量控件 有的话就删除
      if (_that.measurementWidget) _that.measurementWidget.destroy();
      // 将AreaMeasurement2D小部件添加到地图
      _that.measurementWidget = new DistanceMeasurement2D({
        view: view
      });
      // 把控件添加到地图上
      view.ui.add(_that.measurementWidget, "top-left");
    },
    // 面积测量（使用微件）
    instAreaMap() {
      let _that = this;
      // 获取底图
      let view = this.$store.state.mapView;
      // 判断是否添加过测量控件 有的话就删除
      if (_that.measurementWidget) _that.measurementWidget.destroy();
      // 将AreaMeasurement2D小部件添加到地图
        _that.measurementWidget = new AreaMeasurement2D({
        view: view
      });
      // 把控件添加到地图上
      view.ui.add(_that.measurementWidget, "top-left");
    },
    // 自定义距离测量
    customInstDistanceMap() {
      let _that = this;
      // 获取底图
      let view = _that.$store.state.mapView;
      // 实例化一个 GraphicsLayer 图层
      let graphicsLayer = new GraphicsLayer({
        id:'polygonGraphicLayer',
        elevationInfo:{
          mode:'on-the-ground'
        }
      });
      // 把GraphicsLayer图层添加到地图上
      view.map.add(graphicsLayer)
      // 定义一个线的符号化样式 simple-line
      const polylineSymbol = {
        // type = 'simple-fill', 'picture-fill', 'picture-marker', 'simple-line', 'simple-marker', 'text', 'label-3d', 'line-3d', 'mesh-3d', 'point-3d', 'polygon-3d', 'web-style', 'cim')
        type:'simple-line',
        // 填充颜色
        color: '#d81e06',
        // 面状边框样式
        width:2,
        style:'solid'
      }
      // 绘制形状的方法
      const sketchViewModel = new SketchViewModel({
        // Graphic 更新的时候是否触发click事件
        updateOnGraphicClick:false,
        // 绘制的地图
        view,
        // 存放到 graphicsLayer
        layer: graphicsLayer,
        // 样式符号（线）
        polylineSymbol
      });
      // 指定要绘制的形状 polyline代表线（"point 点"|"multipoint"|"polyline 线"|"polygon 面"|"rectangle"|"circle"）
      sketchViewModel.create('polyline');
      // 监听绘制完成事件 create-complete，不支持调用个人定义的方法
      sketchViewModel.on("create-complete", function(event) {
        // 几何图形表现
        const graphic = new Graphic({
          geometry: event.geometry,
          symbol: sketchViewModel.graphic.symbol,
        });
        // 把几何图形添加到新图层上
        GraphicsLayer.add(graphic)
      });
      // 监听绘制事件，绘制完成后执行查询
      sketchViewModel.on("create", function(event) {
        // state === "complete" 也就是绘制完成
        if (event.state === "complete") {
          // 计算服务地址
          const url = 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer';
          // 计算长度参数
          let lengthsParameters = new LengthsParameters();
          lengthsParameters.polylines = event.graphic.geometry; //要计算其长度的折线数组。
          // 9036 代表km的编码
          lengthsParameters.lengthUnit = 9036; //长度单位。
          lengthsParameters.geodesic = true; //如果折线在地理坐标系中，则需要将测地线设置为true，以便计算折线中每对顶点之间的椭圆最短路径距离。
          // 计算长度 geometryService.lengths()
          geometryService.lengths(url,lengthsParameters).then((res) => {
            console.log(res);
          })
        }
      });
    },
    // 自定义面积测量
    customInstAreaMap() {
      let _that = this;
      // 获取底图
      let view = _that.$store.state.mapView;
      // 实例化一个 GraphicsLayer 图层
      let graphicsLayer = new GraphicsLayer({
        id:'polygonGraphicLayer',
        elevationInfo:{
          mode:'on-the-ground'
        }
      });
      // 把GraphicsLayer图层添加到地图上
      view.map.add(graphicsLayer)
      // 定义一个线的符号化样式 simple-line
      const polygonSymbol = {
        // type = 'simple-fill 面', 'picture-fill 线', 'picture-marker', 'simple-line', 'simple-marker', 'text', 'label-3d', 'line-3d', 'mesh-3d', 'point-3d', 'polygon-3d', 'web-style', 'cim')
        type:'simple-fill',
        // 填充颜色
        color: [216, 30, 6, 0.4],
        // 面状边框样式
        style:'solid',
        outline: {
          width: 1,
          color: '#d81e06'
        }
      }
      // 绘制形状的方法
      const sketchViewModel = new SketchViewModel({
        // Graphic 更新的时候是否触发click事件
        updateOnGraphicClick:false,
        // 绘制的地图
        view,
        // 存放到 graphicsLayer
        layer: graphicsLayer,
        // 样式符号（线）
        polygonSymbol
      });
      // 指定要绘制的形状 polyline代表线（"point 点"|"multipoint"|"polyline 线"|"polygon 面"|"rectangle"|"circle"）
      sketchViewModel.create('polygon');
      // 监听绘制完成事件 create-complete，不支持调用个人定义的方法
      sketchViewModel.on("create-complete", function(event) {
        // 几何图形表现
        const graphic = new Graphic({
          geometry: event.geometry,
          symbol: sketchViewModel.graphic.symbol,
        });
        // 把几何图形添加到新图层上
        GraphicsLayer.add(graphic)
      });
      // 监听绘制事件，绘制完成后执行查询
      sketchViewModel.on("create", function(event) {
        // state === "complete" 也就是绘制完成
        if (event.state === "complete") {
          // 计算服务地址
          const url = 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer';
          // 计算面积参数
          let areasAndLengthsParameters = new AreasAndLengthsParameters()
          areasAndLengthsParameters.polygons = event.graphic.geometry; //要为其计算面积和长度的多边形几何图形
          //参数 "acres"|"hectares"|"square-miles"|"square-kilometers 平方公里"|"square-meters"|"square-feet"|"square-yards"
          areasAndLengthsParameters.areaUnit = 'square-kilometers'; //计算多边形面积的面积单位。
          // 参数 "feet"|"kilometers 千米"|"meters"|"miles"|"nautical-miles"|"yards"
          areasAndLengthsParameters.lengthUnit = 'kilometers'; //计算多边形周长的长度单位。
          // 计算面积 geometryService.lengths()
          geometryService.areasAndLengths(url,areasAndLengthsParameters).then((res) => {
            console.log(res);
          })
        }
      });
    },
    // 自定义弹窗
    customPopup() {
      let _that = this;
      // 获取底图
      let view = _that.$store.state.mapView;
      // 获取业务图层
      let topLeary = view.map.findLayerById('layerid');
      if (topLeary) {
        // 图层单击事件
        view.on("click", function (event) {
          // 从与指定屏幕坐标相交的每个图层返回选中结果 hitTest。
          view.hitTest(event).then(function (response) {
            console.log(response);
            if (response.results.length) {
              // 筛选 id=layerid 的图层
              let graphic = response.results.filter(item => {
                console.log(item);
                return item.graphic.layer.id === 'layerid'
              })[0].graphic;
              console.log(graphic.attributes);
              _that.$message({
                showClose: true,
                message: '恭喜你，这是一条成功消息',
                type: 'success'
              });
            }
          });
        });
      } else {
        this.$message({
          message: '请添加业务图层（火车站点）',
          type: 'warning'
        });
      }
    }
  }
}
</script>

<style scoped>
.mpa-tools-view {
  position: absolute;
  height: 30px;
  background: #ffffff;
  top: 20px;
  right: 20px;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.maptools-item {
  line-height: 30px;
  cursor: pointer;
  color: #333;
  font-size: 14px;
  height: 100%;
  display: block;
  padding: 0 10px;
}
.maptools-item:hover {
  background: #3C467C;
  color: #ffffff;
}
.sys-data-index {
  background: #3C467C;
  color: #ffffff!important;
}
/deep/ .el-dropdown {
  height: 100%;
  line-height: 30px;
}
.el-dropdown-link {
  cursor: pointer;
  color: #333333;
  padding: 0 10px;
  display: block;
  height: 100%;
  font-size: 14px;
}
.el-icon-arrow-down {
  font-size: 14px;
}
</style>